#ifndef VECTORX_H
#define VECTORX_H

// Ver. 3.5

namespace sMathLib
{

template<typename T, int dimension>
class VectorX
{

public:

	/// Default constructor
	VectorX();

	/// Constructor for 3-D vector
	VectorX(T x, T y, T z);

	/// Copy constructor
	VectorX(const VectorX &rhs);

	/// Return copy of self
	VectorX clone() const;

public:

	/// Read-write access to member data
	T& operator[](const int index);
	
	/// Read-only access to member data
	const T& operator[](const int index) const;

	/// Read-only access raw data
	const T* data() const;
	
	/// Assignment operators
	VectorX& operator=(const VectorX& rhs);

	VectorX& operator+=(const VectorX& rhs);

	VectorX& operator-=(const VectorX& rhs);

	VectorX& operator*=(const T& rhs);

	/// Explicit arithmetic operators
	T dot(const VectorX& rhs) const;

	T abs() const;

	T normSqr() const;

	T volume() const;
	
	T shift(int index, T& offset) const;

	VectorX<T, dimension> shift(VectorX<T, dimension>& offset) const;

	VectorX<T, dimension> shift(T offsetX, T offsetY, T offsetZ) const;

public:

	const T& x() const { return raw_data[0]; }

	const T& y() const { return raw_data[1]; }

	const T& z() const { return raw_data[2]; }

public:

	const T& u() const { return raw_data[0]; }

	const T& v() const { return raw_data[1]; }

	const T& w() const { return raw_data[2]; }


public:

	static T shiftFrom(T& point, T& offset);

private:

	typedef T VectorData[dimension];
	VectorData raw_data;
};

} // sMathLib





#endif // VECTORX_H
